package tech.yunland.shop.web;

import com.alibaba.fastjson.JSON;
import com.moyuer.bsf.common.Pagination;
import com.moyuer.bsf.domain.model.Organ;
import com.moyuer.bsf.domain.service.OrganService;
import com.moyuer.bsf.web.controller.BaseController;
import org.activiti.engine.IdentityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import tech.yunland.activity.domain.imodel.BaseModel;
import tech.yunland.activity.domain.services.IWorkflowService;
import tech.yunland.shop.domain.model.Goods;
import tech.yunland.shop.domain.model.StoreBill;
import tech.yunland.shop.domain.model.StoreBillEntry;
import tech.yunland.shop.domain.service.SNService;
import tech.yunland.shop.domain.service.StoreBillService;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 出入库单
 */
@RestController
@RequestMapping("/store_bill")
public class StoreBillController extends BaseController {

    @Autowired
    private StoreBillService storeBillService;

    @Autowired
    private SNService snService;

    @Autowired
    private IdentityService identityService;
    @Autowired
    private IWorkflowService<BaseModel> workflowService;

    @Autowired
    private OrganService organService;


    @Value("${processdefId}")
    private String processdefId;

    /**
     * 保存出入库单
     *
     * @param storeBill
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public void save(@RequestBody @Valid StoreBill storeBill) {
        // 输出日志
        logger.info(JSON.toJSONString(storeBill, true));

        // 判断组织
        if (storeBill.getOrgan() == null) {
            storeBill.setOrgan(primaryOrgan);
        }

        // 判断创建人
        if (storeBill.getCreator() == null) {
            storeBill.setCreator(this.currentUser);
        }
        if (storeBill.getEntries() == null || storeBill.getEntries().size() == 0) {
            throw new RuntimeException("参数错误, 没有单据信息");
        }
        if(storeBill.getStoreContiner()!=null){
            String storeContinerId = storeBill.getStoreContiner().getId();
            Organ storeContiner = organService.get(storeContinerId);
            if(!storeContiner.getKindCode().equals("30")){
               // throw new RuntimeException("请选择正确的仓库");
            }
            storeBill.setStoreContiner(storeContiner);
        }

        storeBill.setProcessdefId(processdefId);
        storeBillService.saveStore(storeBill);
        saveLog("库存单:[" + storeBill.getSn() + "]保存成功！");
    }

    /**
     * 查询所有单据
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public Pagination<StoreBill> getAllBill(
            @RequestParam(required = false) String param,
            @RequestParam Integer direction,
            @RequestParam(required = false) List<Integer> states,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows) {

        Pagination<StoreBill> result = new Pagination<StoreBill>(page, rows);
        int startIdx = result.getStartIdx();
        int count = storeBillService.getAllBillSize(param, this.organIds, direction,states);
        List<StoreBill> records = storeBillService.getAllBill(param, this.organIds, direction, startIdx, rows,states);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 根据主键获取出入库单
     *
     * @param id
     */
    @RequestMapping(value = "/save/{id}", method = RequestMethod.GET)
    public StoreBill getStore(@PathVariable String id) {
        return storeBillService.getStore(id);
    }

    /**
     * 根据主键删除出入库单
     *
     * @param id
     * @Return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void deleteStore(@PathVariable String id) {


        storeBillService.deleteStore(id);

    }

    /**
     * 保存分录
     */
    @RequestMapping(value = "/saveEntry", method = RequestMethod.POST)
    public void saveEntry(@RequestBody @Valid StoreBillEntry... billEntries) {

        for (StoreBillEntry billEntry : billEntries) {
            storeBillService.saveEntry(billEntry);
        }
    }

    /**
     * 修改分录
     */
    @RequestMapping(value = "/updateEntry", method = RequestMethod.POST)
    public void updateEntry(@RequestBody @Valid StoreBillEntry billEntry) {
        String id = billEntry.getId();
        StoreBillEntry storeBillEntry = storeBillService.getEntry(id);
        StoreBill storeBill = storeBillEntry.getOwner();
        BigDecimal quantity = billEntry.getQuantity();
        Goods goods = billEntry.getGoods();
        storeBillEntry.setQuantity(quantity);
        storeBillEntry.setOwner(storeBill);
        storeBillEntry.setGoods(goods);
        storeBillService.updateEntry(storeBillEntry);
    }

    /**
     * 查询指定出入库单的所有分录
     *
     * @Return List<SaleBill>
     */
    @RequestMapping(value = "/store", method = RequestMethod.GET)
    public Pagination getStoreBillEntry(
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows,
            @RequestParam String ownerId) {

        Pagination<StoreBillEntry> pagination = new Pagination<>(page, rows);
        Integer startIdx = pagination.getStartIdx();

        pagination.setCount(storeBillService.getStoreBillEntrySize(ownerId));
        pagination.setRecords(storeBillService.getStoreBillEntry(ownerId, startIdx, rows));

        return pagination;
    }

    /**
     * 查询指定出入库单的所有分录 《非分页》
     *
     * @Return List<SaleBill>
     */
    @RequestMapping(value = "/store/list", method = RequestMethod.GET)
    public List<StoreBillEntry> getStoreBillEntryList(@RequestParam String ownerId) {
        List<StoreBillEntry> storeBillEntry = storeBillService.getStoreBillEntry(ownerId, Integer.valueOf(-1), Integer.valueOf(-1));
        return storeBillEntry;
    }

    /**
     * 根据主键查询分录下的商品
     */

    @RequestMapping(value = "/storeBill/{id}", method = RequestMethod.GET)
    public StoreBillEntry getStoreBillInfo(@PathVariable String id) {

        return storeBillService.getEntry(id);

    }

    /**
     * 根据主键删除分录
     */
    @RequestMapping(value = "/store/{id}", method = RequestMethod.DELETE)
    public void deleteStoreEntry(@PathVariable String id) {

        storeBillService.deleteStoreEntry(id);

    }

    /**
     * 启动采购单审批流程
     *
     * @param billId
     */
    @RequestMapping(value = "/runTime", method = RequestMethod.GET)
    public void purchaseBillRunTime(@RequestParam(required = false) String billId) {

        this.identityService.setAuthenticatedUserId(this.currentUser.getId());

        StoreBill storeBill = storeBillService.getStore(billId);

        if (storeBill == null) {
            throw new RuntimeException("该单据数据异常");
        }

        String processdefId = storeBill.getProcessdefId(); //流程ID

        if (StringUtils.isBlank(processdefId)) {
            throw new RuntimeException("该单据没有绑定流程");
        }

        if (storeBill.getState().intValue() == 0) {

            HashMap<String, Object> creatUser = new HashMap<>();
            creatUser.put("creatUser", this.currentUser.getName());

            workflowService.startProcessByPrcessdefId(processdefId, billId, creatUser, this.currentUserId);

            //将单据设置为审核中。
            storeBillService.updateState(billId, 1);

            //更新库存
            storeBillService.updateGoodsStock(storeBill, false, false);

            if (storeBill.getDirection().intValue() == 1) {
                saveLog("入库单：[" + storeBill.getSn() + "] 开始审批！");
            } else if (storeBill.getDirection().intValue() == -1) {
                saveLog("出库单：[" + storeBill.getSn() + "] 开始审批！");
            }
        } else {
            throw new RuntimeException("该单据不能审批");
        }

    }

    /**
     * 执行单据 根据单据ID
     *
     * @param id
     */
    @RequestMapping(value = "/execute/{id}", method = RequestMethod.POST)
    public void executed(@PathVariable String id) {
        storeBillService.updateState(id, 3);
    }

    /**
     * 根据分录进行复核
     * @param entryIds  分录单据ID列表
     * @param storeId   仓库ID
     * @param numbers   复核数量列表
     * @param arrow     1 为入库单据复核  其它为出库单据复核
     * @author 李珂
     *    likenamehaojie@hotmail.com
     */
    @RequestMapping(value = "/execute/", method = RequestMethod.POST)
    public Boolean executedByEntryId(@RequestParam List<String> entryIds, @RequestParam String storeId,@RequestParam List<Double> numbers,@RequestParam Integer arrow){
        if(entryIds.size()!=numbers.size()){
            throw new RuntimeException("非法数据");
        }

        Boolean flag = true;
        if(arrow==1) {//入库
            flag = storeBillService.executedByEntryId(entryIds, storeId, numbers);
        }else {
            flag = storeBillService.executedByEntryIdOut(entryIds,storeId,numbers);
        }
        return flag;

    }
    /**
     * 修改单据备注
     *
     * @param bill
     */
    @RequestMapping(value = "/updateRemark/", method = RequestMethod.POST)
    public void updateBillRemark(@RequestBody StoreBill bill) {
        storeBillService.updateBillRemark(bill.getId(), bill.getRemark());
    }
    /**
     * 拿到未复核完的单据
     */
    @RequestMapping(value = "/get-no-complete-bill",method = RequestMethod.GET)
    public Pagination<Map<String,Object>> getNoCompleteBill(
                                    @RequestParam(required = false) String param,
                                    @RequestParam(required = false) Integer page,
                                    @RequestParam(required = false) Integer rows){
        Pagination<Map<String,Object>> result = new Pagination<Map<String,Object>>(page, rows);
        int startIdx = result.getStartIdx();
        int totalCount  = storeBillService.getNoCompleteBillCount(organIds,param).intValue();
        List<Map<String,Object>> noComplete  =  storeBillService.getNoCompleteBill(this.organIds,rows,startIdx,param);
        result.setRecords(noComplete);
        result.setCount(totalCount);
        return result;
    }

    /**
     * 根据单据号ID拿到分录信息
     * @param page
     * @param rows
     * @return
     */
    @RequestMapping(value = "/get-store-bill-entry/{id}")
    public Pagination<Map<String,Object>> getBillEntry(
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows,
            @PathVariable String id){
        Pagination<Map<String,Object>> result = new Pagination<Map<String,Object>>(page, rows);
        int startIdx = result.getStartIdx();
        int totalCount  = storeBillService.getStoreBillEntrySizeBySql(id).intValue();
        List<Map<String,Object>> allEntrys = storeBillService.getStoreBillEntryBySql(id,startIdx,rows);
        result.setCount(totalCount);
        result.setRecords(allEntrys);
        return result;
    }
}












